package first

import (
	"strings"
)

/*
	输入一个英文句子，翻转句子中单词的顺序，但单词内字符的顺序不变。为简单起见，标点符号和普通字母一样处理。例如输入字符串"I am a student. "，则输出"student. a am I"。

	 

	示例 1：

	输入: "the sky is blue"
	输出: "blue is sky the"
	示例 2：

	输入: "  hello world!  "
	输出: "world! hello"
	解释: 输入字符串可以在前面或者后面包含多余的空格，但是反转后的字符不能包括。
	示例 3：

	输入: "a good   example"
	输出: "example good a"
	解释: 如果两个单词间有多余的空格，将反转后单词间的空格减少到只含一个。
	 

	说明：

	无空格字符构成一个单词。
	输入字符串可以在前面或者后面包含多余的空格，但是反转后的字符不能包括。
	如果两个单词间有多余的空格，将反转后单词间的空格减少到只含一个。
	注意：本题与主站 151 题相同：https://leetcode-cn.com/problems/reverse-words-in-a-string/

	注意：此题对比原题有改动

	来源：力扣（LeetCode）
	链接：https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof
	著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
*/
func ReverseWords(s string) string {
	return reverseWordsTwoPoint(s)
}
func reverseWords(s string) string {
	sli := strings.Split(s, " ")
	ns := make([]string, 0)
	for i := 0; i < len(sli); i++ {
		if sli[i] != "" {
			ns = append(ns, sli[i])
		}
	}
	left, right := 0, len(ns)-1
	for left < right {
		ns[left], ns[right] = ns[right], ns[left]
		left++
		right--
	}
	return strings.Join(ns, " ")
}

func reverseWordsTwoPoint(s string) string {
	for i := 0; i < len(s); i++ {
		if string(s[i]) != " " {
			s = s[i:]
			break
		}
	}
	for j := len(s) - 1; j >= 0; j-- {
		if string(s[j]) != " " {
			s = s[:j+1]
			break
		}
	}
	res := ""
	start, end := len(s)-1, len(s)
	for start >= 0 {
		if s[start] == ' ' {
			if end > start+1 {
				res += s[start+1 : end]
				res += " "
			}
			end = start
		}
		start--
	}
	res += s[start+1 : end]
	return res
}
